﻿#region Using Directives

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using Composite.Layout;
using Composite.Layout.Events;
using Composite.Layout.Extensions;
using LayoutManager.Infrastructure;
using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Commands;
using Microsoft.Practices.Composite.Presentation.Events;
using Microsoft.Practices.Unity;

#endregion

namespace LayoutManager.Modules.Views
{
    public class MenuViewModel : IMenuViewModel, INotifyPropertyChanged
    {
        public static CompositeCommand AddLayoutCommand = new CompositeCommand();
        public static CompositeCommand LoadLayoutCommand = new CompositeCommand();

        private readonly IUnityContainer _Container;
        private readonly IEventAggregator _EventAggregator;
        private readonly IMenuView _View;

        public MenuViewModel(IUnityContainer container, IEventAggregator eventAggregator, IMenuView view)
        {
            _Container = container;
            _EventAggregator = eventAggregator;
            SubscribeToEvents();
            _View = view;
            _View.Model = this;
            BindCommands();
        }

        private DelegateCommand<ILayout> LayoutCommand { get; set; }
        private DelegateCommand<object> AddCommand { get; set; }


        public ObservableCollection<ILayout> Layouts
        {
            get
            {
                var layoutManager = _Container.Resolve<ILayoutManager>();

                if (layoutManager != null)
                {
                    return new ObservableCollection<ILayout>(layoutManager.Layouts);
                }
                return null;
            }
        }

        #region IMenuViewModel Members

        public IMenuView View
        {
            get { return _View; }
        }

        #endregion

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        private void BindCommands()
        {
            LayoutCommand = new DelegateCommand<ILayout>(LayoutCommandExecute);
            LoadLayoutCommand.RegisterCommand(LayoutCommand);
        }

        private bool AddCommandCanExecute(object args)
        {
            var layoutManager = _Container.Resolve<ILayoutManager>();
            return !layoutManager.Layouts.ContainsName("FourthLayout");
        }

        private void AddCommandExecute(object args)
        {
            var layoutManager = _Container.Resolve<ILayoutManager>();
            var control = _Container.Resolve<IFourthLayout>();

            ILayout layout = new Layout
                                 {
                                     Name = "FourthLayout",
                                     Fullname = "Parallel Layout",
                                     Description = "This layout has parallel panes",
                                     ContentControl = control as ContentControl,
                                 };

            var bitmap = new BitmapImage();
            bitmap.BeginInit();
            bitmap.UriSource = new Uri(@"pack://application:,,,/LayoutManager.Infrastructure;component/Resources/Images/layout4.png", UriKind.Absolute);
            bitmap.EndInit();
            layout.ThumbnailSource = bitmap;

            IView view = new View {RegionName = "Left", Type = typeof (IViewA)};
            layout.Views.Add(view);

            view = new ViewModel {RegionName = "Menu", Type = typeof (IMenuViewModel), ViewProperty = "View"};
            layout.Views.Add(view);

            view = new View {RegionName = "Middle", Type = typeof (IViewB)};
            layout.Views.Add(view);

            view = new ViewModel
                       {
                           RegionName = "Right", Type = typeof (IViewModelC), ViewProperty = "View"
                       };
            layout.Views.Add(view);

            layoutManager.Layouts.Add(layout);
            OnPropertyChanged("Layouts");
            AddCommand.RaiseCanExecuteChanged();
        }

        private void LayoutCommandExecute(ILayout layout)
        {
            var layoutManager = _Container.Resolve<ILayoutManager>();
            layoutManager.LoadLayout(layout.Name);
        }

        private void SubscribeToEvents()
        {
            _EventAggregator.GetEvent<LayoutManagerInitializedEvent>().Subscribe(LayoutInitialized, ThreadOption.UIThread);
        }

        private void LayoutInitialized(object args)
        {
            //refresh the Layouts property
            OnPropertyChanged("Layouts");
            AddCommand = new DelegateCommand<object>(AddCommandExecute, AddCommandCanExecute);
            AddLayoutCommand.RegisterCommand(AddCommand);
        }

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }
}